package example.oauth;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class OAuth {
	//public static final String OAUTH_VERSION = "1.0";
	public static final String FORM_ENCODED = "application/x-www-form-urlencoded";
	public static final String ENCODING = "UTF-8"; 
	
    public static final String OAUTH_CONSUMER_KEY = "oauth_consumer_key";
    public static final String OAUTH_TOKEN = "oauth_token";
    public static final String OAUTH_TOKEN_SECRET = "oauth_token_secret";
    public static final String OAUTH_SIGNATURE_METHOD = "oauth_signature_method";
    public static final String OAUTH_SIGNATURE = "oauth_signature";
    public static final String OAUTH_TIMESTAMP = "oauth_timestamp";
    public static final String OAUTH_NONCE = "oauth_nonce";
    public static final String OAUTH_VERSION = "oauth_version";
    public static final String OAUTH_CALLBACK = "oauth_callback";
    //public static final String OAUTH_CALLBACK_CONFIRMED = "oauth_callback_confirmed";
    public static final String OAUTH_VERIFIER = "oauth_verifier";//验证码
	
	public static final String HMAC_SHA1 = "HMAC-SHA1";
    public static final String RSA_SHA1 = "RSA-SHA1";
	
	/*static{
		OAUTH_TIMESTAMP = String.valueOf(System.currentTimeMillis()/1000);//秒数
		OAUTH_NONCE = new MD5().toString();
	}*/
	
   // @SuppressWarnings("unchecked")
	public static String encode(Iterable values) {
        StringBuilder sb = new StringBuilder();
        for (Object obj : values) {
            if (sb.length() > 0) {
                sb.append("&");
            }
            sb.append(OAuth.encode(toString(obj)));
        }
        return sb.toString();
    }
    
    private static final String toString(Object from) {
        return (from == null) ? null : from.toString();
    }
	public static String encode(String str){
		if(null==str){
			return "";
		}
        try {
            return URLEncoder.encode(str, ENCODING)
                    // OAuth encodes some characters differently:
                    .replace("+", "%20").replace("*", "%2A")
                    .replace("%7E", "~");
            // This could be done faster with more hand-crafted code.
        } catch (UnsupportedEncodingException wow) {
            throw new RuntimeException(wow.getMessage(), wow);
        }
	}
    /** Construct a list of Parameters from name, value, name, value... */
    public static List<Parameter> newList(String... parameters) {
    	//System.out.println(parameters.length);
        List<Parameter> list = new ArrayList<Parameter>(parameters.length / 2);
        for (int p = 0; p + 1 < parameters.length; p += 2) {

            list.add(new Parameter(parameters[p], parameters[p + 1]));
            
        }
        Collections.sort(list);
        return list;
    }
    /**
     * Construct a Map containing a copy of the given parameters. If several
     * parameters have the same name, the Map will contain the first value,
     * only.
     
    public static Map<String, String> newMap(Iterable<? extends Map.Entry> from) {
        Map<String, String> map = new HashMap<String, String>();
        if (from != null) {
            for (Map.Entry f : from) {
                String key = toString(f.getKey());
                if (!map.containsKey(key)) {
                    map.put(key, toString(f.getValue()));
                }
            }
        }
        return map;
    }*/
    
    /** A name/value pair. Map.Entry<String, String>*/
    public static class Parameter implements Serializable,Comparable<Parameter>{

		private static final long serialVersionUID = 8131724667315279963L;

		public Parameter(String key, String value) {
            this.key = key;
            this.value = value;
        }

        private final String key;

        private String value;

        public String getKey() {
            return key;
        }

        public String getValue() {
            return value;
        }

        public String setValue(String value) {
            try {
                return this.value;
            } finally {
                this.value = value;
            }
        }

        @Override
        public String toString() {
            return encode(getKey()) + '=' + encode(getValue());
        }

        @Override
        public int hashCode()
        {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((key == null) ? 0 : key.hashCode());
            result = prime * result + ((value == null) ? 0 : value.hashCode());
            return result;
        }

        /*@Override
    	public boolean equals(Object arg0)
    	{
    		if (null == arg0)
    		{
    			return false;
    		}
    		if (this == arg0)
    		{
    			return true;
    		}
    		if (arg0 instanceof Parameter)
    		{
    			Parameter param = (Parameter) arg0;

    			return this.getKey().equals(param.getKey()) && this.getValue().equals(param.getValue());
    		}
    		return false;
    	}*/
        
        
    	@Override
        public boolean equals(Object obj)
        {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            final Parameter that = (Parameter) obj;
            if (key == null) {
                if (that.key != null)
                    return false;
            } else if (!key.equals(that.key))
                return false;
            if (value == null) {
                if (that.value != null)
                    return false;
            } else if (!value.equals(that.value))
                return false;
            return true;
        }

		@Override
		public int compareTo(Parameter param) {
			int compared;
			compared = key.compareTo(param.getKey());
			if (0 == compared)
			{
				compared = value.compareTo(param.getValue());
			}
			return compared;
		}
    }
	
}
